package com.cyp.orderservice.service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.alibaba.nacos.shaded.com.google.gson.reflect.TypeToken;
import com.cyp.common.result.ResultData;
import com.cyp.orderservice.client.OrderClient;
import com.cyp.orderservice.entity.MongoData;
import com.cyp.orderservice.entity.Order;
import com.cyp.orderservice.entity.SpringCloudAllData;
import com.cyp.orderservice.mapper.OrderMapper;
import com.cyp.orderservice.entity.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
@RefreshScope
public class OrderService  {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderClient orderClient;

    @Value("${author}")
    private String author;
    /**
     * 创建订单 减库存
     * @param userId 用户id
     * @param quantity  数量
     * @param amount 金额
     * @return
     */
    public String createOrder(Long userId,Long productId,int quantity,String amount){
        Order order = new Order();
        String productList = orderClient.getProductList();
        log.info("这里是测试配置中心的自动刷新：{}", author);
        log.info("OrderService商品列表：{}", productList);
        order.setOrderNo(UUID.randomUUID().toString());
        order.setUserId(userId);
        order.setProductId(productId);
        order.setQuantity(quantity);
        order.setAmount(new BigDecimal(amount));
        order.setStatus(1);
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        log.info("OrderService执行sql前订单信息：{}",order);
        //创建订单
        orderMapper.insert(order);
        //减库存
        int s = orderClient.updateProduct(quantity, productId, userId);
        if(s>0){
            log.info("OrderService减库存成功");
        }else{
            log.info("OrderService减库存失败");
            return "库存不足";
        }
        String productById = orderClient.getProductById(productId);
        Gson gson = new Gson();
        //存mongo 将下单信息存到mongodb
        //mongoTemplate.createCollection("t_mongo_order_user_info");
        MongoData mongoData = new MongoData();
        mongoData.setOrderId(order.getOrderNo());
        mongoData.setUserId(userId);
        mongoData.setPrcId(productId);
        mongoData.setPrcQuantity(quantity);
        mongoData.setAmount(new BigDecimal(amount));
        mongoData.setCreateTime(new Date());
        mongoData.setStatus("1");
        mongoData.setPrcData(gson.toJson(productById));
        mongoTemplate.insert(mongoData, "t_mongo_order_user_info");
        List<MongoData> list = mongoTemplate.findAll(MongoData.class, "t_mongo_order_user_info");
        log.info("OrderServiceMongoDB数据：{}",list);

        log.info("OrderService执行sql后订单信息：{}",order);
        return gson.toJson(productById);
    }

    /**
     * 测试Sentinel 定义资源和限流降级方法 也可以持久化 用nacos 创建配置文件
     * value = "testOrderSentinel",   资源名，会显示在Sentinel控制台
     * blockHandler = "handleBlock",  流控/熔断时的处理方法
     * fallback = "handleFallback"    异常时的降级方法
     * @return resultData
     */
    @SentinelResource(
            value = "testOrderSentinel",
            blockHandler = "handleBlock",
            fallback = "handleFallback"
    )
    public ResultData<String> testOrderSentinel() {
        ResultData<String> resultData = new ResultData<String>();
        resultData.setCode("200");
        resultData.setMessage("success");
        resultData.setData("测试Sentinel");

        return resultData;
    }

    // 流控/熔断处理方法（必须包含BlockException参数）
    public ResultData<String> handleBlock( BlockException ex) {
        ex.printStackTrace();
        ResultData<String> stringResultData = new ResultData<>();
        stringResultData.setCode("500");
        stringResultData.setMessage("流控/熔断");
        stringResultData.setData("系统繁忙，请稍后再试");
        return stringResultData;
    }

    // 异常降级处理方法
    public ResultData<String> handleFallback(Throwable ex) {
        ex.printStackTrace();
        ResultData<String> stringResultData = new ResultData<>();
        stringResultData.setCode("500");
        stringResultData.setMessage("异常降级");
        stringResultData.setData("系统繁忙，请稍后再试");
        return stringResultData;
    }

    /**
     * 获取所有数据
     * @return SpringCloudAllData
     */
    public SpringCloudAllData getAllData(){
        SpringCloudAllData springCloudAllData = new SpringCloudAllData();

        springCloudAllData.setOrderList(orderMapper.selectList(null));

        String json = orderClient.getProductList();
        List<Product> productList = new Gson().fromJson(json, new TypeToken<List<Product>>(){}.getType());
        springCloudAllData.setProductList(productList);

        springCloudAllData.setMongoDataList(mongoTemplate.findAll(MongoData.class, "t_mongo_order_user_info"));
        springCloudAllData.setRedisDataList(orderClient.getRedis());
        return springCloudAllData;
    }


}
